package com.idealighter.game.backpack.manager;

import com.google.common.eventbus.Subscribe;
import com.google.inject.Inject;
import com.google.inject.Singleton;

import com.idealighter.game.chat.manager.ChatMgr;
import com.idealighter.game.chat.manager.ChatMsgMgr;
import com.idealighter.game.common.CommonMsgMgr;
import com.idealighter.game.core.constant.Operator;
import com.idealighter.game.core.error.ErrorCode;
import com.idealighter.game.dblog.service.DbLogService;
import com.idealighter.game.dictionary.dic.ItemEffectDic;
import com.idealighter.game.dictionary.domain.ItemEffectDomain;
import com.idealighter.game.event.manager.EventMgr;
import com.idealighter.game.event.struct.PlayerLoginEvent;
import com.idealighter.game.log.core.LogReason;
import com.idealighter.game.log.struct.backpack.HornUseLog;
import com.idealighter.game.player.manager.PlayerMgr;
import com.idealighter.game.player.service.bo.PlayerBo;
import com.idealighter.game.player.struct.Player;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 物品管理 .
 * 
 * @date 2015年9月2日 下午6:08:08
 *
 */
@Singleton
public class BackpackMgr {

  private static final Logger LOG = LoggerFactory.getLogger(BackpackMgr.class);

  // vip道具类型
  public static final int VIP = 0;
  // 货币
  public static final int MONEY = 1;
  // 礼品
  public static final int GIFT = 2;
  // 头像
  public static final int ICON = 3;
  // 表情
  public static final int EXPRESSION = 4;
  // 比赛道具
  public static final int COMPETITION = 5;

  @Inject
  private BackpackMsgMgr backpackMsgMgr;
  @Inject
  private PlayerMgr playerMgr;
  @Inject
  private CommonMsgMgr commonMsgMgr;
  @Inject
  private ItemEffectDic itemEffectDic;
  @Inject
  private ChatMsgMgr chatMsgMgr;
  @Inject
  private ChatMgr chatMgr;

  @Inject
  public BackpackMgr(EventMgr eventMgr) {
    eventMgr.register(this);
  }

  /**
   * 订阅玩家登陆事件 .
   * 
   * @param event .
   */
  @Subscribe
  public void onPlayerLogin(PlayerLoginEvent event) {
    backpackMsgMgr.noticeItemInfosMsg(event.player);
  }

  /**
   * 增加道具 .
   * 
   * @param player 玩家.
   * @param itemId .
   * @param num .
   * @param reason .
   */
  public void addItem(Player player, int itemId, int num, LogReason reason) {
    Map<Integer, Integer> items = player.items();
    Integer itemNum = items.get(itemId);
    switch (itemId) {
      case 1: // 元宝
        playerMgr.addIngot(player, num, reason);
        break;
      case 2: // 金币
        playerMgr.addGold(player, num, reason);
        break;
      case 3: // 积分
        playerMgr.addCredit(player, num, reason);
        break;
      case 4: // 奖券
        break;
      default: // 普通物品
        if (itemNum == null) {
          items.put(itemId, num);
        } else {
          items.put(itemId, itemNum + num);
        }

        backpackMsgMgr.sendItemInfoMsg(player, itemId);
        break;
    }
  }

  /**
   * 增加积分 .
   * 
   * @param playerDom .
   * @param itemId .
   * @param num .
   * @param reason .
   */
  public void addItem(PlayerBo playerDom, int itemId, int num, LogReason reason) {
    Map<Integer, Integer> items = playerDom.items();
    Integer itemNum = items.get(itemId);
    switch (itemId) {
      case 1: // 元宝
        playerMgr.addIngot(playerDom, num, reason);
        break;
      case 2: // 金币
        playerMgr.addGold(playerDom, num, reason);
        break;
      case 3: // 积分
        playerMgr.addCredit(playerDom, num, reason);
        break;
      case 4: // 奖券
        break;
      default: // 普通物品
        if (itemNum == null) {
          items.put(itemId, num);
        } else {
          items.put(itemId, itemNum + num);
        }
        break;
    }
  }

  /**
   * 增加积分 .
   * 
   * @param playerId 玩家id.
   * @param itemId .
   * @param num .
   * @param reason .
   */
  public void addItem(long playerId, int itemId, int num, LogReason reason) {
    Player player = playerMgr.getPlayer(playerId);
    if (player != null) {
      addItem(player, itemId, num, reason);
    } else {
      addItem(playerMgr.selectPlayer(playerId), itemId, num, reason);
    }
  }

  /**
   * 移除道具 .
   * 
   * @param player 玩家.
   * @param itemId .
   * @param num .
   * @param reason .
   */
  public void removeItem(Player player, int itemId, int num, LogReason reason) {
    addItem(player, itemId, -num, reason);
  }

  /**
   * 使用道具 .
   * 
   * @param player 玩家.
   * @param itemId .
   * @param num .
   * @param target . 给目标玩家使用 .
   * @param remark . 备注 .
   */
  public void useItem(Player player, int itemId, int num, long target, String remark) {
    Map<Integer, Integer> items = player.items();
    Integer itemNum = items.get(itemId);

    if (itemNum == null || itemNum <= 0) {
      LOG.error("玩家[{}][{}]使用的道具[{}]不存在", player.getPlayerName(), player.getId(), itemId);
      return;
    }

    if (itemNum < num) {
      LOG.error("玩家[{}][{}]使用的道具[{}]数量[{}]多余拥有的道具数量[{}]", player.getPlayerName(), player.getId(),
          itemId, num, itemNum);
      commonMsgMgr.sendErrorDlgMsg(player, ErrorCode.GAME_PROPS_NOT_ENOUGH, Operator.SYSTEM);
      return;
    }

    Player targetPlayer = playerMgr.getPlayer(target);
    if (targetPlayer == null) {
      LOG.error("玩家[{}][{}]使用的道具[{}]针对的玩家[{}]不在线", player.getPlayerName(), player.getId(), itemId,
          target);
      commonMsgMgr.sendErrorDlgMsg(player, ErrorCode.GAME_PROPS_NOT_EFFECT_OFFLINE_PLAYER,
          Operator.SYSTEM);
      return;
    }

    ItemEffectDomain itemEffect = itemEffectDic.get(itemId);
    if (itemEffect.getOther() == 0 && player.getId() != targetPlayer.getId()) {
      LOG.error("玩家[{}][{}]使用的道具[{}]不允许对其他人[{}]使用", player.getPlayerName(), player.getId(), itemId,
          target);
      return;
    }

    // 0：vip会员，2：礼品，3：喇叭才能够使用,喇叭只能自己使用,每次只能使用一个
    switch (itemEffect.getType()) {
      case 0:
        removeItem(player, itemId, num, LogReason.USE_ITEM);
        playerMgr.addVipDuration(targetPlayer, num * itemEffect.getVipDuration());
        break;
      case 2:
        removeItem(player, itemId, num, LogReason.USE_ITEM);
        if (itemEffect.getAttr() > 0 && itemEffect.getAttrNum() != 0) {
          addItem(targetPlayer, itemEffect.getAttr(), num * itemEffect.getAttrNum(),
              LogReason.USE_ITEM);
        }

        if (targetPlayer.isPlayItemEffect()) {
          backpackMsgMgr.sendUsedItemMsg(targetPlayer, player, itemId, num);
        }

        chatMsgMgr.sendSysNoticeMsg(String.format("%s对%s使用了%s个%s，%s的积分增加了%s！",
            player.getPlayerName(), targetPlayer.getPlayerName(), num, itemEffect.getName(),
            targetPlayer.getPlayerName(), num * itemEffect.getAttrNum()));
        break;
      case 3:
        if (num > 1) {
          LOG.error("玩家[{}][{}]使用喇叭的次数不能大于1", player.getPlayerName(), player.getId());
          return;
        }
        if (remark.length() > 650) {
          LOG.error("玩家[{}][{}]使用喇叭的发送的文本超过650个", player.getPlayerName(), player.getId());
          return;
        }
        removeItem(player, itemId, num, LogReason.USE_ITEM);
        chatMsgMgr.sendHornMsg(player.getPlayerName(), chatMgr.filterContent(remark));
        DbLogService.log(new HornUseLog(targetPlayer, remark));
        break;
      default:
        LOG.warn("玩家[{}][{}]使用的道具[{}]不能使用", player.getPlayerName(), player.getId(), itemId);
        break;
    }
  }

  /**
   * 丢弃道具,道具数量为0 .
   * 
   * @param player 玩家.
   * @param itemId .
   */
  public void abandonItem(Player player, int itemId) {
    Map<Integer, Integer> items = player.items();

    if (!items.containsKey(itemId)) {
      LOG.error("玩家[{}][{}]丢弃的道具[{}]不存在", player.getPlayerName(), player.getId(), itemId);
    } else {
      items.put(itemId, 0);
      backpackMsgMgr.sendItemInfoMsg(player, itemId);
    }
  }
}
